package com.ihr360.payroll.controller.salaryreport;

import com.google.common.collect.Lists;
import com.ihr360.commons.entity.AuthUserInfo;
import com.ihr360.commons.exception.Ihr360Exception;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.lang.DateUtils;
import com.ihr360.commons.lang.StringUtils;
import com.ihr360.commons.vo.PageData;
import com.ihr360.maven.plugin.ModuleCodeStore;
import com.ihr360.maven.plugin.annotation.FunctionDefinition;
import com.ihr360.maven.plugin.annotation.ModuleDefinition;
import com.ihr360.payroll.entity.salary.SalaryReportPlanEntity;
import com.ihr360.payroll.model.dto.salary.plan.SalaryPlan;
import com.ihr360.payroll.model.dto.salary.report.MergeSalaryReport;
import com.ihr360.payroll.model.response.salaryreport.MergeSalaryReportResponse;
import com.ihr360.payroll.model.response.salaryreport.SalaryReportResponse;
import com.ihr360.payroll.model.vo.MergeSalaryReportEntity;
import com.ihr360.payroll.model.vo.SalaryPlanVo;
import com.ihr360.payroll.request.salaryReport.MergeSalaryQueryRequest;
import com.ihr360.payroll.request.salaryReport.MergeSalaryReportRequest;
import com.ihr360.payroll.request.salaryReport.SalaryReportRequest;
import com.ihr360.payroll.response.salaryreport.MergeReportMonthResponse;
import com.ihr360.payroll.response.salaryreport.SalaryReportMonthResponse;
import com.ihr360.payroll.service.payperiod.StaffPayPeriodTermSalaryService;
import com.ihr360.payroll.service.salaryplan.SalaryPlanService;
import com.ihr360.payroll.service.salaryreport.HistoryPayPeriodService;
import com.ihr360.payroll.service.salaryreport.HistorySalaryPlanService;
import com.ihr360.payroll.service.salaryreport.MergeSalaryReportService;
import com.ihr360.payroll.service.salaryreport.MergeSalaryReportTermSalaryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * Created by Eric on 2018/4/11/011.
 */
@Api("薪资报表接口")
@RestController
@RequestMapping(value = "/salaryReport")
@ModuleDefinition(mainModuleCode = ModuleCodeStore.Module.SALARY_CODE,
        mainModuleName = ModuleCodeStore.Module.SALARY_NAME,
        subModuleCode = ModuleCodeStore.Module.Salary.SALARY_REPORT_CODE,
        subModuleName = ModuleCodeStore.Module.Salary.SALARY_REPORT_NAME,
        hasExtendsAbstractRestController = false)
public class SalaryReportController {

    @Autowired
    private HistoryPayPeriodService historyPayPeriodService;

    @Autowired
    private HistorySalaryPlanService historySalaryPlanService;

    @Autowired
    private StaffPayPeriodTermSalaryService staffPayPeriodTermSalaryService;

    @Autowired
    private MergeSalaryReportService mergeSalaryReportService;

    @Autowired
    private MergeSalaryReportTermSalaryService mergeSalaryReportTermSalaryService;

    @Autowired
    private SalaryPlanService salaryPlanService;

    @FunctionDefinition(functionName = "薪资方案快照列表", functionCode = ModuleCodeStore.Function.SALARY_REPORT)
    @ApiOperation(value = "/salaryReport/salaryPlanList", notes = "薪资方案快照列表")
    @GetMapping(value = "/salaryPlanList", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public List<SalaryReportPlanEntity> salaryPlanList(AuthUserInfo authUserInfo) {
        List<SalaryReportPlanEntity> list = historySalaryPlanService.getList(authUserInfo.getCompanyId());
        list.addAll(mergeSalaryReportService.getPlanList(authUserInfo.getCompanyId()));
        return list;
    }

    /**
     * 根据薪资方案查询年份列表
     */
    @FunctionDefinition(functionName = "根据薪资方案查询年份列表", functionCode = ModuleCodeStore.Function.SALARY_REPORT)
    @ApiOperation(value = "/salaryReport/yearList", notes = "根据薪资方案查询年份列表")
    @GetMapping(value = "/yearList", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public List<Integer> querySalaryReportYearListList(AuthUserInfo authUserInfo, @RequestParam Long salaryPlanId) {
        return historyPayPeriodService.querySalaryReportYearListList(authUserInfo.getCompanyId(), salaryPlanId);
    }

    /**
     * 根据薪资方案、年份查询该年已有账期的月份列表
     */
    @FunctionDefinition(functionName = "根据薪资方案、年份查询该年已有账期的月份列表", functionCode = ModuleCodeStore.Function.SALARY_REPORT)
    @ApiOperation(value = "/salaryReport/monthList", notes = "根据薪资方案、年份查询该年已有账期的月份列表")
    @GetMapping(value = "/monthList", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public List<SalaryReportMonthResponse> querySalaryReportMonthList(AuthUserInfo authUserInfo, @RequestParam Long salaryPlanId, @RequestParam int year) {
        return historyPayPeriodService.querySalaryReportMonthList(authUserInfo.getCompanyId(), salaryPlanId, year);
    }

    /**
     * 查询薪资报表数据
     */
    @FunctionDefinition(functionName = "根据账期查询员工薪资记录", functionCode = ModuleCodeStore.Function.SALARY_REPORT)
    @ApiOperation(value = "/salaryReport/staffSalary", notes = "根据账期查询员工薪资记录")
    @PostMapping(value = "/staffSalary", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public SalaryReportResponse queryStaffSalary(AuthUserInfo authUserInfo, @RequestBody SalaryReportRequest reportRequest) {
        return staffPayPeriodTermSalaryService.queryStaffSalaryPageData(authUserInfo.getCompanyId(), reportRequest);
    }

    /**
     * 查询薪资报表表头
     */
    @FunctionDefinition(functionName = "查询薪资报表表头", functionCode = ModuleCodeStore.Function.SALARY_REPORT)
    @ApiOperation(value = "/salaryReport/staffSalaryHead", notes = "查询薪资报表表头")
    @PostMapping(value = "/staffSalaryHead", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public SalaryReportResponse queryStaffSalaryHead(AuthUserInfo authUserInfo, @RequestBody SalaryReportRequest reportRequest) {
        //获取表头信息
        SalaryReportResponse reportResponse = new SalaryReportResponse();
        reportResponse.setSalaryHeader(historySalaryPlanService.queryStaffSalaryHead(authUserInfo.getCompanyId(), reportRequest));
        return reportResponse;
    }

    @FunctionDefinition(functionName = "导出薪资报表", functionCode = ModuleCodeStore.Function.EXPORT)
    @ApiOperation(value = "/salaryReport/exportSalaryReport", notes = "导出薪资报表")
    @GetMapping(value = "/exportSalaryReport")
    public void exportSalaryReport(AuthUserInfo authUserInfo, @RequestParam Long termId, @RequestParam Long salaryPlanId, @RequestParam String termDate, HttpServletResponse response) throws IOException {
        response.setHeader("x-filename", URLEncoder.encode("报表结果.xls", "UTF-8"));
        SalaryReportRequest reportRequest = new SalaryReportRequest();
        reportRequest.setTermDate(DateUtils.parse(termDate));
        reportRequest.setTermId(termId);
        reportRequest.setSalaryPlanId(salaryPlanId);
        staffPayPeriodTermSalaryService.exportSalaryReport(authUserInfo.getCompanyId(), reportRequest, response.getOutputStream());
    }

    @FunctionDefinition(functionName = "合并报表列表", functionCode = ModuleCodeStore.Function.MERGE_REPORT)
    @ApiOperation(value = "/salaryReport/mergeReportList", notes = "合并报表列表")
    @PostMapping(value = "/mergeReportList")
    public PageData<MergeSalaryReportResponse> mergeReportList(AuthUserInfo authUserInfo, @RequestBody SalaryReportRequest reportRequest) {
        return mergeSalaryReportService.queryMergeReportList(authUserInfo, reportRequest);
    }

    @FunctionDefinition(functionName = "删除合并报表", functionCode = ModuleCodeStore.Function.MERGE_REPORT)
    @ApiOperation(value = "/salaryReport/deleteMergeReport", notes = "删除合并报表")
    @PostMapping(value = "/deleteMergeReport")
    @Transactional
    public void deleteMergeReport(AuthUserInfo authUserInfo, @RequestParam Long mergeReportId) {
        if (mergeReportId == null) {
            throw new Ihr360Exception(null, "合并报表id为空");
        }
        MergeSalaryReport mergeSalaryReport = mergeSalaryReportService.getOne(mergeReportId);
        if (mergeSalaryReport == null) {
            throw new Ihr360Exception(null, "合并报表不存在");
        }
        if (mergeSalaryReport.getIsMergeTax() != null && mergeSalaryReport.getIsMergeTax()) {
            throw new Ihr360Exception(null, "系统自动生成的合并报表不可删除！");
        }
        mergeSalaryReportService.deleteOne(mergeReportId);
        //删除合并报表账期计算记录
        mergeSalaryReportTermSalaryService.deleteByCompanyIdAndMergeReportId(authUserInfo.getCompanyId(), mergeReportId);
    }

    @FunctionDefinition(functionName = "合并报表设置保存", functionCode = ModuleCodeStore.Function.MERGE_REPORT)
    @ApiOperation(value = "/salaryReport/saveMergeReport", notes = "合并报表设置保存")
    @PostMapping(value = "/saveMergeReport")
    public void saveMergeReport(AuthUserInfo authUserInfo, @RequestBody MergeSalaryReportRequest request) {
        mergeSalaryReportService.saveMergeReport(authUserInfo.getCompanyId(), request);
    }

    @FunctionDefinition(functionName = "合并报表查询详情", functionCode = ModuleCodeStore.Function.MERGE_REPORT)
    @ApiOperation(value = "/salaryReport/queryMergeReportDetail", notes = "合并报表查询详情")
    @GetMapping(value = "/queryMergeReportDetail")
    public MergeSalaryReportEntity queryMergeReportDetail(@RequestParam Long mergeReportId) {
        MergeSalaryReportEntity entity = new MergeSalaryReportEntity();
        MergeSalaryReport mergeSalaryReport = mergeSalaryReportService.getOne(mergeReportId);
        if (mergeSalaryReport == null) {
            throw new Ihr360Exception(null, "合并报表不存在");
        }
        BeanUtils.copyProperties(mergeSalaryReport, entity);
        entity.setId(mergeSalaryReport.getId());
        List<Long> salaryPlanIdList = mergeSalaryReport.getSalaryPlanIdList();
        List<SalaryPlan> salaryPlanList = salaryPlanService.getCompanySalaryPlan(salaryPlanIdList);
        if (CollectionUtils.isNotEmpty(salaryPlanList)) {
            List<SalaryPlanVo> salaryPlanEntityList = Lists.newArrayList();
            for (SalaryPlan salaryPlan : salaryPlanList) {
                SalaryPlanVo salaryPlanEntity = new SalaryPlanVo();
                salaryPlanEntity.setId(salaryPlan.getId());
                salaryPlanEntity.setName(salaryPlan.getName());
                salaryPlanEntity.setPayrollConfig(salaryPlan.getPayrollConfigVo());
                salaryPlanEntityList.add(salaryPlanEntity);
            }
            entity.setSalaryPlanList(salaryPlanEntityList);
        }
        return entity;
    }

    /**
     * 根据合并报表查询年份列表
     */
    @FunctionDefinition(functionName = "根据合并报表查询年份列表", functionCode = ModuleCodeStore.Function.SALARY_REPORT)
    @ApiOperation(value = "/salaryReport/mergeReport/yearList", notes = "根据合并报表查询年份列表")
    @GetMapping(value = "/mergeReport/yearList", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public List<Integer> queryMergeReportYearList(AuthUserInfo authUserInfo, @RequestParam Long salaryPlanId) {
        return mergeSalaryReportService.queryMergeReportYearList(authUserInfo.getCompanyId(), salaryPlanId);
    }

    /**
     * 根据合并报表、年份查询该合并报表月份列表
     */
    @FunctionDefinition(functionName = "根据合并报表、年份查询该合并报表月份列表", functionCode = ModuleCodeStore.Function.SALARY_REPORT)
    @ApiOperation(value = "/salaryReport/mergeReport/monthList", notes = "根据合并报表、年份查询该合并报表月份列表")
    @GetMapping(value = "/mergeReport/monthList", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public List<MergeReportMonthResponse> queryMergeReportMonthList(AuthUserInfo authUserInfo, @RequestParam Long salaryPlanId, @RequestParam int year) {
        return mergeSalaryReportService.queryMergeReportMonthList(authUserInfo.getCompanyId(), salaryPlanId, year);
    }

    @FunctionDefinition(functionName = "查询薪资合并报表结果", functionCode = ModuleCodeStore.Function.SALARY_REPORT)
    @ApiOperation(value = "/salaryReport/queryMergeReportSalaryList", notes = "查询薪资合并报表结果")
    @PostMapping(value = "/queryMergeReportSalaryList")
    public SalaryReportResponse queryMergeReportSalaryList(AuthUserInfo authUserInfo, @RequestBody MergeSalaryQueryRequest reportRequest) {
        return mergeSalaryReportService.queryMergeReportSalaryList(authUserInfo.getCompanyId(), reportRequest);
    }

    @FunctionDefinition(functionName = "查询薪资合并报表表头", functionCode = ModuleCodeStore.Function.SALARY_REPORT)
    @ApiOperation(value = "/salaryReport/queryMergeReportSalaryHead", notes = "查询薪资合并报表表头")
    @PostMapping(value = "/queryMergeReportSalaryHead")
    public SalaryReportResponse queryMergeReportSalaryHead(AuthUserInfo authUserInfo, @RequestBody MergeSalaryQueryRequest reportRequest) {
        return mergeSalaryReportService.queryMergeReportSalaryHead(authUserInfo.getCompanyId(), reportRequest);
    }


    @FunctionDefinition(functionName = "导出薪资合并报表结果", functionCode = ModuleCodeStore.Function.EXPORT)
    @ApiOperation(value = "/salaryReport/exportMergeReportSalaryList", notes = "导出薪资合并报表结果")
    @GetMapping(value = "/exportMergeReportSalaryList")
    public void exportMergeReportSalaryList(AuthUserInfo authUserInfo, @RequestParam Long mergeReportId, @RequestParam Integer indexno,
                                            @RequestParam String termDate, HttpServletResponse response) throws IOException {
        response.setHeader("x-filename", URLEncoder.encode("合并报表结果.xls", "UTF-8"));
        MergeSalaryQueryRequest salaryQueryRequest = new MergeSalaryQueryRequest();
        if (mergeReportId == null || indexno == null || StringUtils.isEmpty(termDate)) {
            throw new Ihr360Exception(null, "请求参数为空");
        }
        salaryQueryRequest.setTermDate(DateUtils.parse(termDate));
        salaryQueryRequest.setIndexno(indexno);
        salaryQueryRequest.setMergeReportId(mergeReportId);
        mergeSalaryReportService.exportMergeReportSalaryList(authUserInfo.getCompanyId(), salaryQueryRequest, response.getOutputStream());
    }

   /* *//**
     * 审批查询薪资报表数据
     *//*
    @FunctionDefinition(functionName = "审批查询薪资报表数据", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "/salaryReport/approval/staffSalary", notes = "审批查询薪资报表数据")
    @PostMapping(value = "/approval/staffSalary", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public SalaryReportResponse queryApprovalStaffSalary(AuthUserInfo authUserInfo, @RequestBody SalaryReportRequest reportRequest, @RequestParam Long historyPayPeriodId) {
        return staffPayPeriodTermSalaryService.queryApprovalStaffSalary(authUserInfo.getCompanyId(), reportRequest, historyPayPeriodId);
    }

    *//**
     * 审批查询薪资报表表头
     *//*
    @FunctionDefinition(functionName = "审批查询薪资报表表头", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "/salaryReport/approval/staffSalaryHead", notes = "审批查询薪资报表表头")
    @GetMapping(value = "/approval/staffSalaryHead", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public SalaryReportResponse queryApprovalStaffSalaryHead(AuthUserInfo authUserInfo, @RequestParam Long historyPayPeriodId) {
        //获取表头信息
        SalaryReportResponse reportResponse = new SalaryReportResponse();
        reportResponse.setSalaryHeader(historySalaryPlanService.queryApprovalStaffSalaryHead(authUserInfo.getCompanyId(), historyPayPeriodId));
        return reportResponse;
    }

    *//**
     * 审批查询历史账期数据
     *//*
    @FunctionDefinition(functionName = "审批查询历史账期数据", functionCode = ModuleCodeStore.Function.VIEW)
    @ApiOperation(value = "/salaryReport/approval/historyPayPeriod", notes = "审批查询历史账期数据")
    @GetMapping(value = "/approval/historyPayPeriod", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public HistoryPayPeriodEntity queryApprovalHistoryPeriod(AuthUserInfo authUserInfo, @RequestParam Long historyPayPeriodId) {
        HistoryPayPeriodEntity entity = new HistoryPayPeriodEntity();
        HistoryPayPeriod historyPayPeriod = historyPayPeriodService.getOne(historyPayPeriodId);
        if (historyPayPeriod == null) {
            throw new Ihr360Exception(null, "该历史账期不存在");
        }
        BeanUtils.copyProperties(historyPayPeriod, entity);
        return entity;
    }*/

}
